<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 6.0.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/wang-cheng/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/wang-cheng/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/wang-cheng/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/wang-cheng/images/logo.svg" color="#222">

<link rel="stylesheet" href="/wang-cheng/css/main.css">


<link rel="stylesheet" href="/wang-cheng/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"cheng-wang123.gitee.io","root":"/wang-cheng/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="开平方根(精确到两位小数)暂无… 实现大数的求和实现线程安全的单例模式队列和栈的应用场景栈：限定仅在表尾进行插入和删除操作的线性表 表尾这一端被称为栈顶，相反地另一端被称为栈底，向栈顶插入元素被称为进栈、入栈、压栈，从栈顶删除元素又称作出栈 队列：队列是一种特殊的线性表，特殊之处在于它只允许在表的前端（front）进行删除操作，而在表的后端（rear）进行插入操作 进行插入操作的端称为队尾，进行删">
<meta property="og:type" content="article">
<meta property="og:title" content="面经一">
<meta property="og:url" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/index.html">
<meta property="og:site_name" content="诚の博客">
<meta property="og:description" content="开平方根(精确到两位小数)暂无… 实现大数的求和实现线程安全的单例模式队列和栈的应用场景栈：限定仅在表尾进行插入和删除操作的线性表 表尾这一端被称为栈顶，相反地另一端被称为栈底，向栈顶插入元素被称为进栈、入栈、压栈，从栈顶删除元素又称作出栈 队列：队列是一种特殊的线性表，特殊之处在于它只允许在表的前端（front）进行删除操作，而在表的后端（rear）进行插入操作 进行插入操作的端称为队尾，进行删">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/MySQL%E9%94%81%E6%9C%BA%E5%88%B6.png">
<meta property="og:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/%E5%86%99%E6%93%8D%E4%BD%9C%E5%86%85%E5%AD%98%E5%B1%8F%E9%9A%9C.png">
<meta property="og:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/synchronized%E5%92%8Clock%E5%8C%BA%E5%88%AB.png">
<meta property="og:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B.png">
<meta property="og:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/TCP%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E5%92%8C%E5%9B%9B%E6%AC%A1%E5%88%86%E6%89%8B.png">
<meta property="og:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/BIO.png">
<meta property="og:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/NIO.png">
<meta property="og:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/%E4%B8%83%E5%B1%82%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B.png">
<meta property="og:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/trap%E4%B8%AD%E6%96%AD.png">
<meta property="article:published_time" content="2022-05-16T09:10:30.000Z">
<meta property="article:modified_time" content="2022-05-19T01:43:10.677Z">
<meta property="article:author" content="王诚">
<meta property="article:tag" content="面经">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/MySQL%E9%94%81%E6%9C%BA%E5%88%B6.png">

<link rel="canonical" href="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>面经一 | 诚の博客</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

<link rel="alternate" href="/wang-cheng/atom.xml" title="诚の博客" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/wang-cheng/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">诚の博客</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">记录学习中的点点滴滴</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/wang-cheng/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/wang-cheng/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/wang-cheng/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/wang-cheng/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://cheng-wang123.gitee.io/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/wang-cheng/images/avatar.gif">
      <meta itemprop="name" content="王诚">
      <meta itemprop="description" content="命运对勇士低语，你无法抵御风暴；勇士低声回应，我就是风暴">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="诚の博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          面经一
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2022-05-16 17:10:30" itemprop="dateCreated datePublished" datetime="2022-05-16T17:10:30+08:00">2022-05-16</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2022-05-19 09:43:10" itemprop="dateModified" datetime="2022-05-19T09:43:10+08:00">2022-05-19</time>
              </span>

          
            <span class="post-meta-item" title="阅读次数" id="busuanzi_container_page_pv" style="display: none;">
              <span class="post-meta-item-icon">
                <i class="fa fa-eye"></i>
              </span>
              <span class="post-meta-item-text">阅读次数：</span>
              <span id="busuanzi_value_page_pv"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h2 id="开平方根-精确到两位小数"><a href="#开平方根-精确到两位小数" class="headerlink" title="开平方根(精确到两位小数)"></a><strong>开平方根(精确到两位小数)</strong></h2><p>暂无…</p>
<h2 id="实现大数的求和"><a href="#实现大数的求和" class="headerlink" title="实现大数的求和"></a><strong>实现大数的求和</strong></h2><h2 id="实现线程安全的单例模式"><a href="#实现线程安全的单例模式" class="headerlink" title="实现线程安全的单例模式"></a><strong>实现线程安全的单例模式</strong></h2><h2 id="队列和栈的应用场景"><a href="#队列和栈的应用场景" class="headerlink" title="队列和栈的应用场景"></a><strong>队列和栈的应用场景</strong></h2><p>栈：限定仅在表尾进行插入和删除操作的线性表</p>
<p>表尾这一端被称为栈顶，相反地另一端被称为栈底，向栈顶插入元素被称为进栈、入栈、压<br>栈，从栈顶删除元素又称作出栈</p>
<p>队列：队列是一种特殊的线性表，特殊之处在于它只允许在表的前端（front）进行删除操作，而在表的后端（rear）进行插入操作</p>
<p>进行插入操作的端称为队尾，进行删除操作的端称为队头，当队列中没有元素时，称为空队列</p>
<p>应用场景：</p>
<ol>
<li><p>栈</p>
<ul>
<li>借助栈的先进后出的特性，可以简单实现一个逆序数处的功能，首先把所有元素依次入栈，然后把所有元素出栈并输出</li>
<li>函数调用和递归的时候，每调用一个函数，底层都会进行入栈操作，出栈则返回函数的返回值</li>
</ul>
</li>
<li><p>队列</p>
<ul>
<li>队列的使用广泛应用在广度优先搜索中，例如层次遍历一个二叉树的节点值</li>
</ul>
</li>
</ol>
<h2 id="重载和重写介绍一下"><a href="#重载和重写介绍一下" class="headerlink" title="重载和重写介绍一下"></a><strong>重载和重写介绍一下</strong></h2><p>重载:发生在同一个类中，方法名必须相同，参数类型不同、个数不同、顺序不同，方法返回值和访问修饰符可以不同，发生在编译时。</p>
<p>重写:发生在子父类，方法名、参数列表必须相同，返回值范围小于等于父类，抛出的异常范围小于等于父类，访问修饰符范围大于等于父类；如果父类方法访问修饰符为private，则子类就不能重写该方法</p>
<h2 id="mysql锁介绍"><a href="#mysql锁介绍" class="headerlink" title="mysql锁介绍"></a><strong>mysql锁介绍</strong></h2><p>不同的存储引擎支持不同的锁机制</p>
<ol>
<li><p>MyISAM和MEMORY存储引擎采用的是表级锁</p>
</li>
<li><p>InnoDB存储引擎既支持行级锁（row-level locking），也支持表级锁，但默认情况下是采用行级锁。</p>
</li>
</ol>
<img src="/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/MySQL%E9%94%81%E6%9C%BA%E5%88%B6.png" class title="MySQL锁机制">
<p>表级锁：开销小，加锁快；不会出现死锁；锁定粒度大，发生锁冲突的概率最高,并发度最低。</p>
<ul>
<li><p>对MyISAM表的读操作，不会阻塞其他用户对同一表的读请求，但会阻塞对同一表的写请求；</p>
</li>
<li><p>对 MyISAM表的写操作，则会阻塞其他用户对同一表的读和写操作；</p>
</li>
<li><p>MyISAM表的读操作与写操作之间，以及写操作之间是串行的（一个处理完才能处理下一个）</p>
</li>
</ul>
<p>行级锁：开销大，加锁慢；会出现死锁；锁定粒度最小，发生锁冲突的概率最低,并发度也最高。</p>
<ul>
<li>行锁就是对数据库表中行记录的锁。比如事务 A，B 同时想要更新一行数据，在更新时一定会按照一定的顺序进行，而不能同时更新。行锁的目的就是减少像表级别的锁冲突，来提升业务的并发度。</li>
</ul>
<p>页锁：开销和加锁时间界于表锁和行锁之间；会出现死锁；锁定粒度界于表锁和行锁之间，并发度一般。</p>
<h2 id="mysql的乐观锁和悲观锁"><a href="#mysql的乐观锁和悲观锁" class="headerlink" title="mysql的乐观锁和悲观锁"></a><strong>mysql的乐观锁和悲观锁</strong></h2><p>悲观锁：顾名思义，就是很悲观，每次去拿数据的时候都认为别人会修改，所以每次在拿数据的时候都会上锁，这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制，比如行锁，表锁等，读锁，写锁等，都是在做操作之前先上锁。</p>
<p>乐观锁：顾名思义，就是很乐观，每次去拿数据的时候都认为别人不会修改，所以不会上锁，但是在更新的时候会判断一下在此期间别人有没有去更新这个数据，可以使用版本号等机制。</p>
<h2 id="mysql索引类型"><a href="#mysql索引类型" class="headerlink" title="mysql索引类型"></a><strong>mysql索引类型</strong></h2><p>1、普通索引：是最基本的索引，它没有任何限制</p>
<p>2、唯一索引：索引列的值必须唯一，但允许有空值。</p>
<p>3、主键索引：是一种特殊的唯一索引，一个表只能有一个主键，不允许有空值。一般是在建表的时候同时创建主键索引</p>
<p>4、组合索引：指多个字段上创建的索引，只有在查询条件中使用了创建索引时的第一个字段，索引才会被使用。使用组合索引时遵循最左前缀集合</p>
<p>5、全文索引：主要用来查找文本中的关键字，而不是直接与索引中的值相比较</p>
<h2 id="mysql隔离级别"><a href="#mysql隔离级别" class="headerlink" title="mysql隔离级别"></a><strong>mysql隔离级别</strong></h2><p>读未提交</p>
<p>读已提交</p>
<p>可重复读</p>
<p>序列化</p>
<h2 id="介绍一下innodb和myasiam区别"><a href="#介绍一下innodb和myasiam区别" class="headerlink" title="介绍一下innodb和myasiam区别"></a><strong>介绍一下innodb和myasiam区别</strong></h2><ol>
<li><p>InnoDB支持事务，MyISAM不支持，对于InnoDB每一条SQL语言都默认封装成事务，自动提交，这样会影响速度，所以最好把多条SQL语言放在begin和commit之间，组成一个事务； </p>
</li>
<li><p>InnoDB支持外键，而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败； </p>
</li>
<li><p>InnoDB是聚集索引，使用B+Tree作为索引结构，数据文件是和（主键）索引绑在一起的（表数据文件本身就是按B+Tree组织的一个索引结构），必须要有主键，通过主键索引效率很高。但是辅助索引需要两次查询，先查询到主键，然后再通过主键查询到数据。因此，主键不应该过大，因为主键太大，其他索引也都会很大。</p>
</li>
<li><p>InnoDB不保存表的具体行数，执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数，执行上述语句时只需要读出该变量即可，速度很快（注意不能加有任何WHERE条件）；</p>
</li>
<li><p>Innodb不支持全文索引，而MyISAM支持全文索引，在涉及全文索引领域的查询效率上MyISAM速度更快高；PS：5.7以后的InnoDB支持全文索引了</p>
</li>
<li><p>MyISAM表格可以被压缩后进行查询操作</p>
</li>
<li><p>InnoDB支持表、行(默认)级锁，而MyISAM支持表级锁</p>
</li>
<li><p>InnoDB表必须有唯一索引（如主键）（用户没有指定的话会自己找/生产一个隐藏列Row_id来充当默认主键），而Myisam可以没有</p>
</li>
<li><p>Innodb存储文件有frm、ibd，而Myisam是frm、MYD、MYI</p>
<ul>
<li>Innodb：frm是表定义文件，ibd是数据文件</li>
<li>Myisam：frm是表定义文件，myd是数据文件，myi是索引文件</li>
</ul>
</li>
</ol>
<h2 id="Redis的K和V最大能存储多大内存"><a href="#Redis的K和V最大能存储多大内存" class="headerlink" title="Redis的K和V最大能存储多大内存"></a><strong>Redis的K和V最大能存储多大内存</strong></h2><ul>
<li><p>虽然Key的大小上限为512M，但是一般建议key的大小不要超过1KB,这样既可以节约存储空间，又有利于Redis进行检索</p>
</li>
<li><p>value的最大值也是512M.对于String类型的value值上限为512M，而集合、链表、哈希等key类型，单个元素的value上限也为512M。</p>
</li>
</ul>
<h2 id="防止缓存击穿"><a href="#防止缓存击穿" class="headerlink" title="防止缓存击穿"></a><strong>防止缓存击穿</strong></h2><ul>
<li><p>设置热点数据永远不过期</p>
</li>
<li><p>加互斥锁</p>
</li>
</ul>
<h2 id="CMS过程、CMS的哪个过程是STW-初始化阶段STW吗？为什么"><a href="#CMS过程、CMS的哪个过程是STW-初始化阶段STW吗？为什么" class="headerlink" title="CMS过程、CMS的哪个过程是STW,初始化阶段STW吗？为什么"></a><strong>CMS过程、CMS的哪个过程是STW,初始化阶段STW吗？为什么</strong></h2><p><code>STW(Stop-The-World)</code>: 是在垃圾回收算法执⾏过程当中，将JVM内存冻结、应用程序停顿的⼀种状态。</p>
<ol>
<li><p>初始标记（STW）:这个阶段的主要任务仅仅只是标记出GC Roots能直接关联到的对象，速度比较快，不用担心会停顿太长时间。</p>
</li>
<li><p>并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程，这个过程耗时较长但是不需要停顿用户线程，可以与垃圾收集线程一起并发运行。</p>
</li>
<li><p>重新标记（STW）:由于并发标记阶段可能某些用户线程会导致标记产生变动，因此这里需要再次暂停所有线程进行并发标记，这个时间会比初始标记时间长一点。</p>
</li>
<li><p>并发清除:最后就可以直接将所有标记好的无用对象进行删除，因为这些对象程序中也用不到了，所以可以与用户线程并发运行。</p>
</li>
</ol>
<p><strong>初始标记为什么需要STW？</strong></p>
<p>因为初始标记标记的是GC Root，而GC Root容易变动，比如栈帧中的本地变量表。所以需要STW。</p>
<p><strong>重新标记为什么需要STW？</strong></p>
<p>因为在重新标记之前是并发标记，在并发标记的期间会出现漏标和多标的对象，所以为了修正这部分对象，需要在重新标记期间STW。</p>
<h2 id="HashMap为什么不安全"><a href="#HashMap为什么不安全" class="headerlink" title="HashMap为什么不安全"></a><strong>HashMap为什么不安全</strong></h2><ol>
<li><p>put的时候导致的多线程数据不一致：</p>
<p> 这个问题比较好想象，比如有两个线程A和B，首先A希望插入一个key-value对到HashMap中，首先计算记录所要落到的桶的索引坐标，然后获取到该桶里面的链表头结点，此时线程A的时间片用完了，而此时线程B被调度得以执行，和线程A一样执行，只不过线程B成功将记录插到了桶里面，假设线程A插入的记录计算出来的桶索引和线程B要插入的记录计算出来的桶索引是一样的，那么当线程B成功插入之后，线程A再次被调度运行时，它依然持有过期的链表头但是它对此一无所知，以至于它认为它应该这样做，如此一来就覆盖了线程B插入的记录，这样线程B插入的记录就凭空消失了，造成了数据不一致的行为。</p>
</li>
<li><p>扩容的时候导致的死循环</p>
</li>
</ol>
<h2 id="TreeSet和HashSet介绍一下"><a href="#TreeSet和HashSet介绍一下" class="headerlink" title="TreeSet和HashSet介绍一下"></a><strong>TreeSet和HashSet介绍一下</strong></h2><ul>
<li><p>TreeSet：红黑树结构，每一个元素都是树中的一个节点，插入的元素都会进行排序；</p>
<ul>
<li>对插入的元素进行排序，是一个有序的集合（主要与HashSet的区别）</li>
<li>底层使用红黑树结构，而不是哈希表结构</li>
<li>允许插入Null值</li>
<li>不允许插入重复元素</li>
<li>线程不安全</li>
</ul>
</li>
<li><p>HashSet：哈希表结构，主要利用HashMap的key来存储元素，计算插入元素的hashCode来获取元素在集合中的位置</p>
<ul>
<li>不允许出现重复因素</li>
<li>允许插入Null值</li>
<li>元素无序（添加顺序和遍历顺序不一致）</li>
<li>线程不安全，若2个线程同时操作HashSet，必须通过代码实现同步</li>
</ul>
</li>
</ul>
<h2 id="runnable和callable介绍一下"><a href="#runnable和callable介绍一下" class="headerlink" title="runnable和callable介绍一下"></a><strong>runnable和callable介绍一下</strong></h2><ol>
<li><p>Runnable只执行逻辑，不返回结果；Callable执行逻辑之后，会返回结果。</p>
</li>
<li><p>Runnable不支持抛出受检异常，异常需要自己在run()方法的实现中消化；Callable可以抛出异常。（方法定义上肉眼可见的差别）</p>
</li>
<li><p>Runnable的实现类可以通过构造方法直接传递给一个Thread，并执行；而Callable只能借助Future去执行并获取返回结果。</p>
</li>
</ol>
<h2 id="线程池拒绝策略"><a href="#线程池拒绝策略" class="headerlink" title="线程池拒绝策略"></a><strong>线程池拒绝策略</strong></h2><p>AbortPolicy:丢弃任务，并抛出拒绝执行的异常信息RejectedExecutionException</p>
<p>DiscardPolicy：直接丢弃</p>
<p>DiscardOldestPolicy：丢弃阻塞队列中最老的任务，将新任务加入</p>
<p>CallerRunsPolicy：当有新任务提交后，如果线程池没被关闭且没有能力执行，则把这个任务交于提交任务的线程执行，也就是谁提交任务，谁就负责执行任务</p>
<h2 id="什么是线程安全，为什么不安全"><a href="#什么是线程安全，为什么不安全" class="headerlink" title="什么是线程安全，为什么不安全"></a><strong>什么是线程安全，为什么不安全</strong></h2><p>当多个线程访问一个对象时，如果不用考虑这些线程在运行时环境下的调度和交替执行，并且不需要额外的同步，或者在调用方代码不做其他的协调操作，这个对象的行为获取的结果仍然是正确的，那个称这个对象是线程安全的，否则就是不安全</p>
<p>为什么不安全呢？</p>
<ol>
<li><p>CPU抢占执行</p>
</li>
<li><p>非原子性</p>
</li>
<li><p>编译器优化（指令重排） 编译器优化在单线程下执行没问题，多线程下优化会发生混乱</p>
</li>
<li><p>内存的不可见性</p>
</li>
<li><p>多个线程修改了同一个变量</p>
</li>
</ol>
<h2 id="一般怎么样才能做到线程安全"><a href="#一般怎么样才能做到线程安全" class="headerlink" title="一般怎么样才能做到线程安全"></a><strong>一般怎么样才能做到线程安全</strong></h2><p>原子性、可见性、有序性</p>
<h2 id="volatile原理、功能"><a href="#volatile原理、功能" class="headerlink" title="volatile原理、功能"></a><strong>volatile原理、功能</strong></h2><p>功能：</p>
<ol>
<li>保证变量的可见性<ul>
<li>当一个被volatile关键字修饰的变量被一个线程修改的时候，其他线程可以立刻得到修改之后的结果。当一个线程向被volatile关键字修饰的变量写入数据的时候，虚拟机会强制它被值刷新到主内存中。当一个线程用到被volatile关键字修饰的值的时候，虚拟机会强制要求它从主内存中读取。</li>
</ul>
</li>
<li>屏蔽指令重排序<ul>
<li>指令重排序是编译器和处理器为了高效对程序进行优化的手段，它只能保证程序执行的结果时正确的，但是无法保证程序的操作顺序与代码顺序一致。这在单线程中不会构成问题，但是在多线程中就会出现问题。非常经典的例子是在单例方法中同时对字段加入voliate，就是为了防止指令重排序。</li>
</ul>
</li>
</ol>
<p><strong>可见性</strong></p>
<p>简单来说：当一个共享变量被volatile修饰时，它会保证修改的值会立即被更新到主存，当有其他线程需要读取时，它会去内存中读取新值。</p>
<p><strong>禁止重排序</strong></p>
<p>volatile禁止重排序是利用内存屏障，保证有序性。</p>
<p>(1) volatile会在变量写操作的前后加入两个内存屏障，来保证前面的写指令和后面的读指令是有序的。</p>
<img src="/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/%E5%86%99%E6%93%8D%E4%BD%9C%E5%86%85%E5%AD%98%E5%B1%8F%E9%9A%9C.png" class title="写操作内存屏障 } (2) volatile在变量的读操作后面插入两个指令，禁止后面的读指令和写指令重排序。 {% asset_img 读操作内存屏障.png 读操作内存屏障">
<h2 id="synchronized和lock的区别"><a href="#synchronized和lock的区别" class="headerlink" title="synchronized和lock的区别"></a><strong>synchronized和lock的区别</strong></h2><img src="/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/synchronized%E5%92%8Clock%E5%8C%BA%E5%88%AB.png" class title="synchronized和lock区别">
<ol>
<li><p>来源：lock是一个接口，而synchronized是java的一个关键字，synchronized是内置的语言实现；</p>
</li>
<li><p>异常是否释放锁：synchronized在发生异常时候会自动释放占有的锁，因此不会出现死锁；而lock发生异常时候，不会主动释放占有的锁，必须手动unlock来释放锁，可能引起死锁的发生。（所以最好将同步代码块用try catch包起来，finally中写入unlock，避免死锁的发生。）</p>
</li>
<li><p>是否响应中断：lock等待锁过程中可以用interrupt来中断等待，而synchronized只能等待锁的释放，不能响应中断；</p>
</li>
<li><p>是否知道获取锁：Lock可以通过trylock来知道有没有获取锁，而synchronized不能；</p>
</li>
<li><p>Lock可以提高多个线程进行读操作的效率。（可以通过readwritelock实现读写分离）</p>
</li>
<li><p>在性能上来说，如果竞争资源不激烈，两者的性能是差不多的，而当竞争资源非常激烈时（即有大量线程同时竞争），此时Lock的性能要远远优于synchronized。所以说，在具体使用时要根据适当情况选择。</p>
</li>
<li><p>synchronized使用Object对象本身的wait 、notify、notifyAll调度机制，而Lock可以使用Condition进行线程之间的调度</p>
</li>
</ol>
<p>synchronized原始采用的是CPU悲观锁机制，即线程获得的是独占锁。独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换，当有很多线程竞争锁的时候，会引起CPU频繁的上下文切换导致效率很低。</p>
<p>而Lock用的是乐观锁方式。所谓乐观锁就是，每次不加锁而是假设没有冲突而去完成某项操作，如果因为冲突失败就重试，直到成功为止。乐观锁实现的机制就是CAS操作</p>
<h2 id="synchronized什么时候给类加锁"><a href="#synchronized什么时候给类加锁" class="headerlink" title="synchronized什么时候给类加锁"></a><strong>synchronized什么时候给类加锁</strong></h2><p>类锁是锁住整个类的，当有多个线程来声明这个类的对象的时候将会被阻塞，直到拥有这个类锁的对象被销毁或者主动释放了类锁。这个时候在被阻塞住的线程被挑选出一个占有该类锁，声明该类的对象。其他线程继续被阻塞住。父类加了类锁，子类是不会收到影响的，相反也是如此。</p>
<h2 id="输入一个URL，到最终页面呈现经历了哪些过程"><a href="#输入一个URL，到最终页面呈现经历了哪些过程" class="headerlink" title="输入一个URL，到最终页面呈现经历了哪些过程"></a><strong>输入一个URL，到最终页面呈现经历了哪些过程</strong></h2><ol>
<li><p>DNS(域名系统)解析(如果IP直接访问则此过程省略)</p>
<ul>
<li>DNS是一个由分层的DNS服务器实现的分布式数据库，</li>
<li>DNS是一个使得主机能够查询分布式数据库的应用层协议</li>
<li>DNS运行在UDP上，使用53端口</li>
<li>先查浏览器缓存，再查host文件，再查DNS服务器</li>
</ul>
</li>
<li><p>构造HTTP协议的数据报</p>
<ul>
<li>从浏览器中输入，那请求方式是GET，加上报文头。然后将数据报交给运输层。</li>
</ul>
</li>
<li><p>客户端与服务器端进行TCP三次握手连接</p>
<img src="/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B.png" class title="三次握手">
</li>
<li><p>TCP把数据构造成一个TCP数据报</p>
<ul>
<li>在此之前已经完成了三次握手，那么这一步在TCP构造完后交给IP协议</li>
</ul>
</li>
<li><p>IP 协议构造成一个 IP 数据报</p>
<ul>
<li>此处要根据数据报的长度，以及MTU 的限制，考虑是否分包，如果需要分包，根据Ip报文中的16位标识符（标识是否是同一个包），13位偏移位（标识先后顺序），3位标志位（表示结束标记位）进行分包。包分完之后，需要查路由表，决定从哪个端口转发，完成上述步骤后，将数据交给数据链路层。</li>
</ul>
</li>
<li><p>构造一个以太网数据帧</p>
<ul>
<li>源mac，就是本机mac。</li>
<li>目的mac，根据上面 IP 确定的转发端口来决定的。</li>
</ul>
</li>
<li><p>物理层</p>
<ul>
<li>转换成光信号或者电信号，进行传输。</li>
</ul>
</li>
<li><p>传输到下一台路由器上</p>
<ul>
<li>路由器进行解析和分用（解析到传输层）</li>
<li>路由选择，继续查路由表</li>
<li>把数据再次封装，往下一个路由器设备上转发</li>
</ul>
</li>
<li><p>中间会经历若干路由器转发的过程…</p>
<ul>
<li>最终到达目标服务器，服务器又会进行分用。</li>
</ul>
</li>
<li><p>物理层把光电信号转换成二进制bit流，交给数据链路层</p>
</li>
<li><p>数据链路层解析出其中的 IP 数据报，交给网络层</p>
</li>
<li><p>网络层可能需要组包，解析出其中的传输层数据，交给传输层</p>
</li>
<li><p>TCP解析出其中的应用层数据，交给应用程序</p>
</li>
<li><p>服务器的应用程序，读取数据，根据请求计算响应，得到一个html页面</p>
</li>
<li><p>把页面构造成一个http响应报文，经过一系列的封装，分用，传输，最终回到客户端</p>
</li>
<li><p>浏览器解析渲染页面</p>
</li>
<li><p>连接结束</p>
</li>
</ol>
<h2 id="cookie和session区别"><a href="#cookie和session区别" class="headerlink" title="cookie和session区别"></a><strong>cookie和session区别</strong></h2><ul>
<li><p>安全性：Session 比 Cookie 安全，Session 是存储在服务器端的，Cookie 是存储在客户端的。</p>
</li>
<li><p>存取值的类型不同：Cookie 只支持存字符串数据，想要设置其他类型的数据，需要将其转换成字符串，Session 可以存任意数据类型。</p>
</li>
<li><p>有效期不同： Cookie 可设置为长时间保持，比如我们经常使用的默认登录功能，Session 一般失效时间较短，客户端关闭（默认情况下）或者 Session 超时都会失效。</p>
</li>
<li><p>存储大小不同： 单个 Cookie 保存的数据不能超过 4K，Session 可存储数据远高于 Cookie，但是当访问量过多，会占用过多的服务器资源。</p>
</li>
</ul>
<h2 id="TCP和UDP的区别"><a href="#TCP和UDP的区别" class="headerlink" title="TCP和UDP的区别"></a><strong>TCP和UDP的区别</strong></h2><ol>
<li><p>TCP面向连接（如打电话要先拨号建立连接）;UDP是无连接的，即发送数据之前不需要建立连接</p>
</li>
<li><p>TCP提供可靠的服务。也就是说，通过TCP连接传送的数据，无差错，不丢失，不重复，且按序到达;UDP尽最大努力交付，即不保 证可靠交付</p>
</li>
<li><p>TCP面向字节流，实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的<br>UDP没有拥塞控制，因此网络出现拥塞不会使源主机的发送速率降低（对实时应用很有用，如IP电话，实时视频会议等）</p>
</li>
<li><p>每一条TCP连接只能是点到点的;UDP支持一对一，一对多，多对一和多对多的交互通信</p>
</li>
<li><p>TCP首部开销20字节;UDP的首部开销小，只有8个字节</p>
</li>
<li><p>TCP的逻辑通信信道是全双工的可靠信道，UDP则是不可靠信道</p>
</li>
</ol>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/u012957549/article/details/105108120">https://blog.csdn.net/u012957549/article/details/105108120</a></p>
<h2 id="TCP三次握手和TCP四次挥手"><a href="#TCP三次握手和TCP四次挥手" class="headerlink" title="TCP三次握手和TCP四次挥手"></a><strong>TCP三次握手和TCP四次挥手</strong></h2><img src="/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/TCP%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E5%92%8C%E5%9B%9B%E6%AC%A1%E5%88%86%E6%89%8B.png" class title="TCP三次握手和四次分手">
<p><strong>三次握手</strong></p>
<ol>
<li><p>第一次握手：建立连接。客户端发送连接请求报文段，将SYN位置为1，Sequence Number为x;然后，客户端进入SYN_SEND状态，等待服务器的确认;</p>
</li>
<li><p>第二次握手：服务器收到SYN报文段。服务器收到客户端的SYN报文段，需要对这个SYN报文段进行确认，设置Acknowledgment Number为x+1(Sequence Number+1);同时，自己自己还要发送SYN请求信息，将SYN位置为1，Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中，一并发送给客户端，此时服务器进入SYN_RECV状态;</p>
</li>
<li><p>第三次握手：客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1，向服务器发送ACK报文段，这个报文段发送完毕以后，客户端和服务器端都进入ESTABLISHED状态，完成TCP三次握手。</p>
</li>
</ol>
<p>完成了三次握手，客户端和服务器端就可以开始传送数据</p>
<p><strong>四次挥手</strong></p>
<ol>
<li><p>主机1(可以使客户端，也可以是服务器端)，设置Sequence Number和Acknowledgment Number，向主机2发送一个FIN报文段;此时，主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;</p>
</li>
<li><p>主机2收到了主机1发送的FIN报文段，向主机1回一个ACK报文段，Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2进入CLOSE_WAIT状态;</p>
</li>
<li><p>主机2向主机1发送FIN报文段，表示我也没有数据要发送了，请求关闭连接，同时主机2进入LAST_ACK状态;</p>
</li>
<li><p>主机1收到主机2发送的FIN报文段，向主机2发送ACK报文段，然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后，就关闭连接;此时，主机1等待2MSL后依然没有收到回复，则证明Server端已正常关闭，那好，主机1也可以关闭连接了。</p>
</li>
</ol>
<h2 id="TCP为什么要三次握手"><a href="#TCP为什么要三次握手" class="headerlink" title="TCP为什么要三次握手"></a><strong>TCP为什么要三次握手</strong></h2><p>为了防止已失效的连接请求报文段突然又传送到了服务端，因而产生错误。</p>
<p><strong>举例：</strong></p>
<p>“已失效的连接请求报文段”的产生在这样一种情况下：client发出的第一个连接请求报文段并没有丢失，而是在某个网络结点长时间的滞留了，以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后，就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段，同意建立连接。假设不采用“三次握手”，那么只要server发出确认，新的连接就建立了。由于现在client并没有发出建立连接的请求，因此不会理睬server的确认，也不会向server发送数据。但server却以为新的运输连接已经建立，并一直等待client发来数据。这样，server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况，client不会向server的确认发出确认。server由于收不到确认，就知道client并没有要求建立连接。”</p>
<h2 id="TCP为什么要四次挥手"><a href="#TCP为什么要四次挥手" class="headerlink" title="TCP为什么要四次挥手"></a><strong>TCP为什么要四次挥手</strong></h2><p>那四次分手又是为何呢?TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工 模式，这就意味着，当主机1发出FIN报文段时，只是表示主机1已经没有数据要发送了，主机1告诉主机2， 它的数据已经全部发送完毕了;但是，这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文 段时，表示它已经知道主机1没有数据发送了，但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN 报文段时，这个时候就表示主机2也没有数据要发送了，就会告诉主机1，我也没有数据要发送了，之后彼此 就会愉快的中断这次TCP连接。如果要正确的理解四次分手的原理，就需要了解四次分手过程中的状态变化。</p>
<ul>
<li><p>FIN_WAIT_1: 这个状态要好好解释一下，其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等 待对方的FIN报文。而这两种状态的区别是：FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时， 它想主动关闭连接，向对方发送了FIN报文，此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报 文后，则进入到FIN_WAIT_2状态，当然在实际的正常情况下，无论对方何种情况下，都应该马上回应ACK 报文，所以FIN_WAIT_1状态一般是比较难见到的，而FIN_WAIT_2状态还有时常常可以用netstat看到。 (主动方)</p>
</li>
<li><p>FIN_WAIT_2：上面已经详细解释了这种状态，实际上FIN_WAIT_2状态下的SOCKET，表示半连接，也即 有一方要求close连接，但另外还告诉对方，我暂时还有点数据需要传送给你(ACK信息)，稍后再关闭连接。 (主动方)</p>
</li>
<li><p>CLOSE_WAIT：这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN 报文给自己，你系统毫无疑问地会回应一个ACK报文给对方，此时则进入到CLOSE_WAIT状态。接下来呢，实 际上你真正需要考虑的事情是察看你是否还有数据发送给对方，如果没有的话，那么你也就可以 close这个 SOCKET，发送FIN报文给对方，也即关闭连接。所以你在CLOSE_WAIT状态下，需要完成的事情是等待你去关闭连接。(被动方)</p>
</li>
<li><p>LAST_ACK: 这个状态还是比较容易好理解的，它是被动关闭一方在发送FIN报文后，最后等待对方的ACK报 文。当收到ACK报文后，也即可以进入到CLOSED可用状态了。(被动方)</p>
</li>
<li><p>TIME_WAIT: 表示收到了对方的FIN报文，并发送出了ACK报文，就等2MSL后即可回到CLOSED可用状态了。 如果FINWAIT1状态下，收到了对方同时带FIN标志和ACK标志的报文时，可以直接进入到TIME_WAIT状态，而无 须经过FIN_WAIT_2状态。(主动方)</p>
</li>
<li><p>CLOSED: 表示连接中断。</p>
</li>
</ul>
<h2 id="http请求码常见的说一下，401和403说一下"><a href="#http请求码常见的说一下，401和403说一下" class="headerlink" title="http请求码常见的说一下，401和403说一下"></a><strong>http请求码常见的说一下，401和403说一下</strong></h2><ol>
<li><p>1xx（临时响应）表示临时响应并需要请求者继续执行操作的状态代码</p>
<ul>
<li>100（继续）请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分，正在等待其余部分</li>
<li>101（切换协议）请求者已要求服务器切换协议，服务器已确认并准备切换</li>
</ul>
</li>
<li><p>2xx（成功）表示服务器成功处理了请求的状态代码</p>
<ul>
<li>200（成功）服务器已成功处理了请求。通常，这表示服务器提供了请求的网页.如果针对您的 robots.txt 文件显示此状态，则表示 Googlebot 已成功检索到该文件</li>
<li>201（已创建）请求成功并且服务器创建了新的资源</li>
<li>202（已接受）服务器已接受请求，但尚未处理</li>
<li>203（非授权信息）服务器已成功处理了请求，但返回的信息可能来自另一来源</li>
<li>204（无内容）服务器成功处理了请求，但没有返回任何内容</li>
<li>205（重置内容）服务器成功处理了请求，但没有返回任何内容。 与 204 响应不同，此响应要求请求者重置文档视图（例如，清除表单内容以输入新内容）</li>
<li>206（部分内容）服务器成功处理了部分 GET 请求</li>
</ul>
</li>
<li><p>3xx（重定向）要完成请求，需要进一步操作。 通常，这些状态代码用来重定向。</p>
</li>
<li><p>4xx（请求错误）这些状态代码表示请求可能出错，妨碍了服务器的处理</p>
<ul>
<li>400（错误请求）服务器不理解请求的语法</li>
<li>401（未授权）请求要求身份验证。 对于需要登录的网页，服务器可能返回此响应</li>
<li>403（禁止）服务器拒绝请求。 如果您看到 Googlebot 在尝试抓取您网站上的有效网页时收到此状态代码（可以在 Google 网站管理员工具诊 断下的网络抓取页面上看到此信息），可能是您的服务器或主机拒绝Googlebot 访问</li>
<li>404（未找到）服务器找不到请求的网页。 例如，如果请求服务器上不存在的网页，服务器通常会返回此代码。如果您的网站上没有 robots.txt 文件，而您在 Google 网站管理员工具”诊断”标签的robots.txt 页上看到此状态，那么这是正确的状态。 但是，如果您有 robots.txt 文件而又看到此状态，则说明您的 robots.txt 文件可能命名错误或位于错误的位置 （该文件应当位于顶级域名，名为robots.txt）。如果您看到有关 Googlebot 尝试抓取的网址的此状态（在”诊断”标签的 HTTP 错误页上），则表示 Googlebot 追踪的可能是另一个页面的无效链接（是旧链接或输入有误的链接）</li>
<li>405（禁用的方法）禁用请求中指定的方法</li>
<li>406（不可接受）无法使用请求的内容特性响应请求的网页</li>
<li>407（需要代理授权）此状态代码与 401（未授权）类似，但指定请求者应当授权使用代理。 如果服务器返回此响应，还会指明请求者应当使用的代理</li>
<li>408（请求超时）服务器等候请求时发生超时</li>
</ul>
</li>
</ol>
<h2 id="http请求方式-get-post…"><a href="#http请求方式-get-post…" class="headerlink" title="http请求方式(get/post…)"></a><strong>http请求方式(get/post…)</strong></h2><ol>
<li><p>GET请求指定的页面信息，并返回实体主体</p>
</li>
<li><p>POST向指定资源提交数据进行处理请求（例如提交表单或者上传文件）。数据被包含在请求体中，post请求可能会导致新的资源的建立和/或已有资源的修改</p>
</li>
<li><p>Head类似于get请求，只不过返回的响应中没有具体的内容，用于获取报头</p>
</li>
<li><p>Options允许客户端查看服务器的性能</p>
</li>
<li><p>Put从客户端向服务器传送的数据取代指定的文档的内容</p>
</li>
<li><p>Delete请求服务器删除指定的页面</p>
</li>
<li><p>Trace回显服务器收到的请求，主要用于测试或诊断</p>
</li>
<li><p>PATCH对 PUT 方法的补充，用来对已知资源进行局部更新。</p>
</li>
<li><p>CONNECT能够将连接改为管道方式的代理服务器。</p>
</li>
</ol>
<h2 id="http和https的区别"><a href="#http和https的区别" class="headerlink" title="http和https的区别"></a><strong>http和https的区别</strong></h2><ol>
<li><p>Http和https使用完全不同的连接方法和不同的端口。前者是80，后者是443。Http连接是非常简单和无状态的；HttpS协议是由SSL/TLS+HTTP协议构建的网络协议，可用于加密传输和身份认证。它比HTTP协议更安全。</p>
</li>
<li><p>超文本传输协议，缩写为HTTP，是分布式、协作式和超媒体信息系统的应用层协议，是万维网数据通信的基础，也是互联网上使用最广泛的网络传输协议。HTTP最初被设计为提供一种发布和接收HTML页面的方式。</p>
</li>
<li><p>HTTPS协议之所以安全，是因为HTTPS协议对传输的数据进行加密，而加密过程是由非对称加密实现的。然而，HTTPS在内容传输的加密过程中使用对称加密，而非对称加密只在证书验证阶段发挥作用。</p>
</li>
</ol>
<h2 id="BIO和NIO的区别"><a href="#BIO和NIO的区别" class="headerlink" title="BIO和NIO的区别"></a><strong>BIO和NIO的区别</strong></h2><ul>
<li><p>BIO是传统的Java IO编程，其基本的类和接口在java.io包中</p>
</li>
<li><p>BIO(blocking I/O)：同步阻塞，服务器实现模式为一个连接一个线程，即客户端有连接请求时服务器端就需要启动一个线程进行处理，如果这个连接不做任何事情会造成不必要的线程开销</p>
</li>
<li><p>BIO方式使用于连接数目比较小且固定的架构，这种服务方式对服务器资源要求比价高，并且局限于应用中，JDK1.4以前的唯一选择，程序简单易理解</p>
</li>
</ul>
<p>基本模型：<br><img src="/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/BIO.png" class title="BIO"></p>
<ul>
<li><p>NIO全称 java non-blocking IO。从JDK 1.4开始，java提供了一些列改进的输入/输出（I/O）的新特性，被称为NIO，是同步非阻塞的</p>
</li>
<li><p>NIO相关类都被放在java.nio包及其子包下</p>
</li>
<li><p>NIO三大核心部分：Channel（通道），Buffer（缓冲区），Selector（选择器）</p>
</li>
<li><p>NIO是面向缓冲区的，或者面向块编程的。数据读取到一个它稍后处理的缓冲区，需要时可在缓冲区内前后移动，这就增加了处理过程中的灵活性，使用它可以提供非阻塞的高伸缩性网络</p>
</li>
<li><p>Java NIO的非阻塞模式，使一个线程从某通道发送或者读取数据，但是它仅能得到目前可用的数据，如果目前没有可用的数据时，就什么都不会获取，而不是保持线程阻塞，所以直至数据变的可读取之前，该线程可以继续做其他事情。非阻塞就是如此，一个线程请求写入一些数据到某通道，但不需要等待它完全写入，这个线程同时可以去做别的事情</p>
</li>
<li><p>通俗来讲：NIO是可以做到用一个线程处理多个操作的。假设有10000个请求过来，根据实际情况，可以分配50或100个线程来处理。不想BIO一样需要分配10000个线程来处理</p>
</li>
</ul>
<p>基本模型：</p>
<img src="/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/NIO.png" class title="NIO">
<p>其中Selector（选择器）的作用是循环监听多个客户端连接通道，如果通道中没有数据即客户端没有请求时它可以去处理别的通道或者做其他的事情，如果通道中有数据他就会选择这个通道然后进行处理，这就做到了一个线程处理多个连接。</p>
<p>区别：</p>
<ul>
<li><p>NIO以流的方式处理数据，NIO以块的方式处理数据，块IO的效率比流IO高很多。（比如说流IO他是一个流，你必须时刻去接着他，不然一些流就会丢失造成数据丢失，所以处理这个请求的线程就阻塞了他无法去处理别的请求，他必须时刻盯着这个请求防止数据丢失。而块IO就不一样了，线程可以等他的数据全部写入到缓冲区中形成一个数据块然后再去处理他，在这期间该线程可以去处理其他请求）</p>
</li>
<li><p>BIO是阻塞的，NIO是非阻塞的</p>
</li>
<li><p>BIO基于字节流和字符流进行操作的，而NIO基于Channel（通道）和Buffer（缓冲区）进行操作的，数据总是从通道读取到缓冲区中，或者从缓冲区写入到通道中。Selector（选择器）用于监听多个通道事件，因此使用单个线程就可以监听多个客户端通道</p>
</li>
</ul>
<h2 id="ArrayList的扩容"><a href="#ArrayList的扩容" class="headerlink" title="ArrayList的扩容"></a><strong>ArrayList的扩容</strong></h2><ul>
<li><p>ArrayList每次扩容都是原来的1.5倍</p>
</li>
<li><p>数组进行扩容时，会将老数组中的元素重新拷贝一份到新数组中，每次数组容量的增长大约是其原容量的1.5倍</p>
</li>
<li><p>代价是很高的，因此在实际使用时，我们应该尽量避免数组容量的扩张。尽可能，就指定其容量，以避免数组扩容的发生</p>
</li>
<li><p>创建方式不同，容量不同</p>
</li>
</ul>
<p>ArrayList扩容过程：</p>
<p>当使用无参构造时，并不会立即扩容，而是在第一次使用add()方法时才会扩容。</p>
<p>当调用add()方法添加元素，会在方法内部判断ArrayList是否已经达到最大容量。如果达到了最大容量，则调用grow()方法进行扩容。</p>
<p>在grow()方法中会进行是否是无参构造第一次扩容的判断，如果是，则默认扩容大小为10，如果不是，则调用newLength()方法计算应该扩容的大小，一般为1.5倍，然后调用Arrays.copyOf()方法，将原数组元素转移到扩容后的新数组当中，完成数据迁移</p>
<h2 id="网络的模型"><a href="#网络的模型" class="headerlink" title="网络的模型"></a><strong>网络的模型</strong></h2><img src="/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/%E4%B8%83%E5%B1%82%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B.png" class title="七层网络模型">
<h2 id="事务的隔离性"><a href="#事务的隔离性" class="headerlink" title="事务的隔离性"></a><strong>事务的隔离性</strong></h2><p>隔离机制</p>
<ul>
<li><p>读未提交：一个事务还没有提交前，它做的变更能被别的事务看见</p>
</li>
<li><p>读已提交：一个事务提交后，其变更才能被其他事务看见</p>
</li>
<li><p>可重复读：一个事务执行过程中看见的数据，和这个事务在启动时一致（被其他事物修改也没用）。在此机制下，未提交变更对其他事务也是不可见的</p>
</li>
<li><p>串行化：对于数据操作，写会加写锁，读会加读锁。当出现读写锁冲突时，后访问的事务必须等前一个事务执行完成，才能继续执行。</p>
</li>
</ul>
<p>一般我们将Mysql的隔离级别设置为”读提交”</p>
<ol>
<li><p>“读未提交” 隔离级别下，直接返回记录上的最新值，没有视图概念。</p>
</li>
<li><p>“读提交” 隔离级别下，视图是在每个查询 SQL 语句开始执行时创建的。</p>
</li>
<li><p>“可重复读” 隔离级别下，视图是在事务启动时创建的，整个事务执行期间都用这个视图。</p>
</li>
<li><p>“串行化” 隔离级别下，直接用加锁的方式来避免并行访问，不创建视图。</p>
</li>
</ol>
<p>MVCC的内容等……</p>
<h2 id="内核态和用户态的区别"><a href="#内核态和用户态的区别" class="headerlink" title="内核态和用户态的区别"></a><strong>内核态和用户态的区别</strong></h2><h3 id="用户态和内核态"><a href="#用户态和内核态" class="headerlink" title="用户态和内核态"></a><strong>用户态和内核态</strong></h3><p>用户空间中的代码被限制了只能使用一个局部的内存空间，我们说这些程序在用户态（User Mode） 执行。内核空间中的代码可以访问所有内存，我们称这些程序在内核态（Kernal Mode） 执行。</p>
<p>如果用户态程序需要执行系统调用，就需要切换到内核态执行</p>
<img src="/wang-cheng/2022/05/16/%E9%9D%A2%E7%BB%8F%E4%B8%80/trap%E4%B8%AD%E6%96%AD.png" class title="trap中断">
<p>内核程序执行在内核态（Kernal Mode），用户程序执行在用户态（User Mode）。当发生系统调用时，用户态的程序发起系统调用。因为系统调用中牵扯特权指令，用户态程序权限不足，因此会中断执行，也就是 Trap（Trap 是一种中断）。</p>
<p>发生中断后，当前 CPU 执行的程序会中断，跳转到中断处理程序。内核程序开始执行，也就是开始处理系统调用。内核处理完成后，主动触发 Trap，这样会再次发生中断，切换回用户态工作。</p>
<h3 id="用户态切换到内核态的三种方式"><a href="#用户态切换到内核态的三种方式" class="headerlink" title="用户态切换到内核态的三种方式"></a><strong>用户态切换到内核态的三种方式</strong></h3><ol>
<li><p>系统调用：这是用户态进程主动要求切换到内核态的一种方式，用户态进程通过系统调用申请使 用操作系统提供的服务程序完成工作，比如前例中fork()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操作系统为用户 特别开放的一个中断来实现。</p>
</li>
<li><p>异常：当CPU在执行运行在用户态下的程序时，发生了某些事先不可知的异常，这时会触发由当前运行进程切换到处理此异常的内核相关程序中，也就转到了内核态，比如缺页异常。</p>
</li>
<li><p>外围设备的中断：当外围设备完成用户请求的操作后，会向CPU发出相应的中断信号，这时CPU会 暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序，如果先前执行的指令是用户态下的程序，那么这个转换的过程自然也就发生了由用户态到 内核态的切换。比如硬盘读写操作完成，系统会切换到硬盘读写的中断处理程序中执行后续操作等。</p>
</li>
</ol>
<h2 id="DNS协议是怎么实现的，用到了什么协议"><a href="#DNS协议是怎么实现的，用到了什么协议" class="headerlink" title="DNS协议是怎么实现的，用到了什么协议"></a><strong>DNS协议是怎么实现的，用到了什么协议</strong></h2><p>DNS(域名解析)协议能够将域名映射成IP地址</p>
<p>域名服务器是指管理域名的主机和相应的软件，它可以管理所在分层的域的相关信息。一个域名服务器所负责管理的分层叫作 区 (ZONE)。域名的每层都设有一个域名服务器：</p>
<ul>
<li>根域名服务器</li>
<li>顶级域名服务器</li>
<li>权限域名服务器</li>
</ul>
<h3 id="DNS-查询方式"><a href="#DNS-查询方式" class="headerlink" title="DNS 查询方式"></a><strong>DNS 查询方式</strong></h3><ul>
<li><p>递归查询</p>
</li>
<li><p>迭代查询</p>
</li>
</ul>
<h3 id="完整域名解析过程"><a href="#完整域名解析过程" class="headerlink" title="完整域名解析过程"></a><strong>完整域名解析过程</strong></h3><ol>
<li><p>首先搜索浏览器的 DNS 缓存，缓存中维护一张域名与 IP 地址的对应表；</p>
</li>
<li><p>若没有命中，则继续搜索操作系统的 DNS 缓存；</p>
</li>
<li><p>若仍然没有命中，则操作系统将域名发送至本地域名服务器，本地域名服务器查询自己的 DNS 缓存，查找成功则返回结果（注意：主机和本地域名服务器之间的查询方式是递归查询）；</p>
</li>
<li><p>若本地域名服务器的 DNS 缓存没有命中，则本地域名服务器向上级域名服务器进行查询，通过以下方式进行迭代查询（注意：本地域名服务器和其他域名服务器之间的查询方式是迭代查询，防止根域名服务器压力过大）</p>
<ul>
<li><p>首先本地域名服务器向根域名服务器发起请求，根域名服务器是最高层次的，它并不会直接指明这个域名对应的 IP 地址，而是返回顶级域名服务器的地址，也就是说给本地域名服务器指明一条道路，让他去这里寻找答案。</p>
</li>
<li><p>本地域名服务器拿到这个顶级域名服务器的地址后，就向其发起请求，获取权限域名服务器的地址。</p>
</li>
<li><p>本地域名服务器根据权限域名服务器的地址向其发起请求，最终得到该域名对应的 IP 地址。</p>
</li>
</ul>
</li>
<li><p>本地域名服务器将得到的 IP 地址返回给操作系统，同时自己将 IP 地址缓存起来。</p>
</li>
<li><p>操作系统将 IP 地址返回给浏览器，同时自己也将 IP 地址缓存起来。</p>
</li>
<li><p>至此，浏览器就得到了域名对应的 IP 地址，并将 IP 地址缓存起来。</p>
</li>
</ol>
<h2 id="TCP怎么保证可靠性-相关的协议、算法"><a href="#TCP怎么保证可靠性-相关的协议、算法" class="headerlink" title="TCP怎么保证可靠性(相关的协议、算法)"></a><strong>TCP怎么保证可靠性(相关的协议、算法)</strong></h2><ul>
<li><p>首先，TCP 的连接是基于三次握手，而断开则是四次挥手。确保连接和断开的可靠性。</p>
</li>
<li><p>其次，TCP 的可靠性，还体现在有状态;TCP 通过校验和、ACK 应答、超时重传来记录哪些数据发送了，哪些数据被接受了，哪些没有被接受，并且保证数据包按序到达，保证数据传输不出差错。</p>
</li>
<li><p>再次，TCP 的可靠性，还体现在可控制。通过流量控制（滑动窗口）和拥塞控制来控制发送方发送速率。</p>
</li>
</ul>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/u014401141/article/details/122961741">https://blog.csdn.net/u014401141/article/details/122961741</a></p>
<h2 id="String底层是怎么实现的"><a href="#String底层是怎么实现的" class="headerlink" title="String底层是怎么实现的"></a><strong>String底层是怎么实现的</strong></h2><p>底层最主要的实现是 final char[ ]; final修饰后当这个属性第一次被赋值后就不可以改变了，所以当我们拼接字符串的时候，每次拼接都会创建一个新的对象。所以不允许大量的拼接，否则会产生大量的对象，影响性能。</p>
<h2 id="OSI和ICP-IP的联系"><a href="#OSI和ICP-IP的联系" class="headerlink" title="OSI和ICP/IP的联系"></a><strong>OSI和ICP/IP的联系</strong></h2><p>osi模型是一个简称，全名为开放式系统互联通信参考模型，这是一种概念上的模型，是由国际标准化组织提出的一个概念。</p>
<p>tcp也是个简称，全名为传输控制协议，这是一种面向有连接的，十分可靠的，并且是基础字节流的传输层通信协议。</p>
<p>ip是国籍互联协议的缩写，是tcp/ip这个体系中的网络层协议。</p>
<p>相同点：</p>
<ul>
<li><p>两个协议都分层；</p>
</li>
<li><p>OSI参考模型的网络层与TPC/IP互联网层的功能几乎相同；</p>
</li>
<li><p>以传输层为界，上层都依赖传输层提供端到端的，与网络环境无关的传输服务。</p>
</li>
</ul>
<p>不同点：</p>
<ul>
<li><p>TCP/IP并未对网络接口层细分</p>
</li>
<li><p>OSI分层模型在前，协议规范灾后</p>
</li>
<li><p>OSI对服务和协议做了特别明显的区别，而TCP/IP并没有细分。</p>
</li>
<li><p>OSI为7层模型，TCP/IP为5层模型</p>
</li>
<li><p>TCP/IP模型的第三层仅支持IP协议，OSI支持所有的网络层协议</p>
</li>
</ul>

    </div>

    
    
    

      <footer class="post-footer">
          <div class="post-tags">
              <a href="/wang-cheng/tags/%E9%9D%A2%E7%BB%8F/" rel="tag"># 面经</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/wang-cheng/2022/05/05/synchronized%E7%AD%89%E9%94%81%E6%9C%BA%E5%88%B6/" rel="prev" title="synchronized等锁机制">
      <i class="fa fa-chevron-left"></i> synchronized等锁机制
    </a></div>
      <div class="post-nav-item">
    <a href="/wang-cheng/2022/05/20/%E9%9D%A2%E7%BB%8F%E4%BA%8C/" rel="next" title="面经二">
      面经二 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%BC%80%E5%B9%B3%E6%96%B9%E6%A0%B9-%E7%B2%BE%E7%A1%AE%E5%88%B0%E4%B8%A4%E4%BD%8D%E5%B0%8F%E6%95%B0"><span class="nav-number">1.</span> <span class="nav-text">开平方根(精确到两位小数)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%AE%9E%E7%8E%B0%E5%A4%A7%E6%95%B0%E7%9A%84%E6%B1%82%E5%92%8C"><span class="nav-number">2.</span> <span class="nav-text">实现大数的求和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%AE%9E%E7%8E%B0%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F"><span class="nav-number">3.</span> <span class="nav-text">实现线程安全的单例模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%98%9F%E5%88%97%E5%92%8C%E6%A0%88%E7%9A%84%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="nav-number">4.</span> <span class="nav-text">队列和栈的应用场景</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%87%8D%E8%BD%BD%E5%92%8C%E9%87%8D%E5%86%99%E4%BB%8B%E7%BB%8D%E4%B8%80%E4%B8%8B"><span class="nav-number">5.</span> <span class="nav-text">重载和重写介绍一下</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#mysql%E9%94%81%E4%BB%8B%E7%BB%8D"><span class="nav-number">6.</span> <span class="nav-text">mysql锁介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#mysql%E7%9A%84%E4%B9%90%E8%A7%82%E9%94%81%E5%92%8C%E6%82%B2%E8%A7%82%E9%94%81"><span class="nav-number">7.</span> <span class="nav-text">mysql的乐观锁和悲观锁</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#mysql%E7%B4%A2%E5%BC%95%E7%B1%BB%E5%9E%8B"><span class="nav-number">8.</span> <span class="nav-text">mysql索引类型</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#mysql%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB"><span class="nav-number">9.</span> <span class="nav-text">mysql隔离级别</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BB%8B%E7%BB%8D%E4%B8%80%E4%B8%8Binnodb%E5%92%8Cmyasiam%E5%8C%BA%E5%88%AB"><span class="nav-number">10.</span> <span class="nav-text">介绍一下innodb和myasiam区别</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Redis%E7%9A%84K%E5%92%8CV%E6%9C%80%E5%A4%A7%E8%83%BD%E5%AD%98%E5%82%A8%E5%A4%9A%E5%A4%A7%E5%86%85%E5%AD%98"><span class="nav-number">11.</span> <span class="nav-text">Redis的K和V最大能存储多大内存</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%98%B2%E6%AD%A2%E7%BC%93%E5%AD%98%E5%87%BB%E7%A9%BF"><span class="nav-number">12.</span> <span class="nav-text">防止缓存击穿</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#CMS%E8%BF%87%E7%A8%8B%E3%80%81CMS%E7%9A%84%E5%93%AA%E4%B8%AA%E8%BF%87%E7%A8%8B%E6%98%AFSTW-%E5%88%9D%E5%A7%8B%E5%8C%96%E9%98%B6%E6%AE%B5STW%E5%90%97%EF%BC%9F%E4%B8%BA%E4%BB%80%E4%B9%88"><span class="nav-number">13.</span> <span class="nav-text">CMS过程、CMS的哪个过程是STW,初始化阶段STW吗？为什么</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#HashMap%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E5%AE%89%E5%85%A8"><span class="nav-number">14.</span> <span class="nav-text">HashMap为什么不安全</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#TreeSet%E5%92%8CHashSet%E4%BB%8B%E7%BB%8D%E4%B8%80%E4%B8%8B"><span class="nav-number">15.</span> <span class="nav-text">TreeSet和HashSet介绍一下</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#runnable%E5%92%8Ccallable%E4%BB%8B%E7%BB%8D%E4%B8%80%E4%B8%8B"><span class="nav-number">16.</span> <span class="nav-text">runnable和callable介绍一下</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%BA%BF%E7%A8%8B%E6%B1%A0%E6%8B%92%E7%BB%9D%E7%AD%96%E7%95%A5"><span class="nav-number">17.</span> <span class="nav-text">线程池拒绝策略</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E5%AE%89%E5%85%A8"><span class="nav-number">18.</span> <span class="nav-text">什么是线程安全，为什么不安全</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%B8%80%E8%88%AC%E6%80%8E%E4%B9%88%E6%A0%B7%E6%89%8D%E8%83%BD%E5%81%9A%E5%88%B0%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8"><span class="nav-number">19.</span> <span class="nav-text">一般怎么样才能做到线程安全</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#volatile%E5%8E%9F%E7%90%86%E3%80%81%E5%8A%9F%E8%83%BD"><span class="nav-number">20.</span> <span class="nav-text">volatile原理、功能</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#synchronized%E5%92%8Clock%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="nav-number">21.</span> <span class="nav-text">synchronized和lock的区别</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#synchronized%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E7%BB%99%E7%B1%BB%E5%8A%A0%E9%94%81"><span class="nav-number">22.</span> <span class="nav-text">synchronized什么时候给类加锁</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%BE%93%E5%85%A5%E4%B8%80%E4%B8%AAURL%EF%BC%8C%E5%88%B0%E6%9C%80%E7%BB%88%E9%A1%B5%E9%9D%A2%E5%91%88%E7%8E%B0%E7%BB%8F%E5%8E%86%E4%BA%86%E5%93%AA%E4%BA%9B%E8%BF%87%E7%A8%8B"><span class="nav-number">23.</span> <span class="nav-text">输入一个URL，到最终页面呈现经历了哪些过程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#cookie%E5%92%8Csession%E5%8C%BA%E5%88%AB"><span class="nav-number">24.</span> <span class="nav-text">cookie和session区别</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#TCP%E5%92%8CUDP%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="nav-number">25.</span> <span class="nav-text">TCP和UDP的区别</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#TCP%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E5%92%8CTCP%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B"><span class="nav-number">26.</span> <span class="nav-text">TCP三次握手和TCP四次挥手</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#TCP%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B"><span class="nav-number">27.</span> <span class="nav-text">TCP为什么要三次握手</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#TCP%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B"><span class="nav-number">28.</span> <span class="nav-text">TCP为什么要四次挥手</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#http%E8%AF%B7%E6%B1%82%E7%A0%81%E5%B8%B8%E8%A7%81%E7%9A%84%E8%AF%B4%E4%B8%80%E4%B8%8B%EF%BC%8C401%E5%92%8C403%E8%AF%B4%E4%B8%80%E4%B8%8B"><span class="nav-number">29.</span> <span class="nav-text">http请求码常见的说一下，401和403说一下</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#http%E8%AF%B7%E6%B1%82%E6%96%B9%E5%BC%8F-get-post%E2%80%A6"><span class="nav-number">30.</span> <span class="nav-text">http请求方式(get&#x2F;post…)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#http%E5%92%8Chttps%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="nav-number">31.</span> <span class="nav-text">http和https的区别</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#BIO%E5%92%8CNIO%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="nav-number">32.</span> <span class="nav-text">BIO和NIO的区别</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#ArrayList%E7%9A%84%E6%89%A9%E5%AE%B9"><span class="nav-number">33.</span> <span class="nav-text">ArrayList的扩容</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%BD%91%E7%BB%9C%E7%9A%84%E6%A8%A1%E5%9E%8B"><span class="nav-number">34.</span> <span class="nav-text">网络的模型</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BA%8B%E5%8A%A1%E7%9A%84%E9%9A%94%E7%A6%BB%E6%80%A7"><span class="nav-number">35.</span> <span class="nav-text">事务的隔离性</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%86%85%E6%A0%B8%E6%80%81%E5%92%8C%E7%94%A8%E6%88%B7%E6%80%81%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="nav-number">36.</span> <span class="nav-text">内核态和用户态的区别</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%94%A8%E6%88%B7%E6%80%81%E5%92%8C%E5%86%85%E6%A0%B8%E6%80%81"><span class="nav-number">36.1.</span> <span class="nav-text">用户态和内核态</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%94%A8%E6%88%B7%E6%80%81%E5%88%87%E6%8D%A2%E5%88%B0%E5%86%85%E6%A0%B8%E6%80%81%E7%9A%84%E4%B8%89%E7%A7%8D%E6%96%B9%E5%BC%8F"><span class="nav-number">36.2.</span> <span class="nav-text">用户态切换到内核态的三种方式</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#DNS%E5%8D%8F%E8%AE%AE%E6%98%AF%E6%80%8E%E4%B9%88%E5%AE%9E%E7%8E%B0%E7%9A%84%EF%BC%8C%E7%94%A8%E5%88%B0%E4%BA%86%E4%BB%80%E4%B9%88%E5%8D%8F%E8%AE%AE"><span class="nav-number">37.</span> <span class="nav-text">DNS协议是怎么实现的，用到了什么协议</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#DNS-%E6%9F%A5%E8%AF%A2%E6%96%B9%E5%BC%8F"><span class="nav-number">37.1.</span> <span class="nav-text">DNS 查询方式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%AE%8C%E6%95%B4%E5%9F%9F%E5%90%8D%E8%A7%A3%E6%9E%90%E8%BF%87%E7%A8%8B"><span class="nav-number">37.2.</span> <span class="nav-text">完整域名解析过程</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#TCP%E6%80%8E%E4%B9%88%E4%BF%9D%E8%AF%81%E5%8F%AF%E9%9D%A0%E6%80%A7-%E7%9B%B8%E5%85%B3%E7%9A%84%E5%8D%8F%E8%AE%AE%E3%80%81%E7%AE%97%E6%B3%95"><span class="nav-number">38.</span> <span class="nav-text">TCP怎么保证可靠性(相关的协议、算法)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#String%E5%BA%95%E5%B1%82%E6%98%AF%E6%80%8E%E4%B9%88%E5%AE%9E%E7%8E%B0%E7%9A%84"><span class="nav-number">39.</span> <span class="nav-text">String底层是怎么实现的</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#OSI%E5%92%8CICP-IP%E7%9A%84%E8%81%94%E7%B3%BB"><span class="nav-number">40.</span> <span class="nav-text">OSI和ICP&#x2F;IP的联系</span></a></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">王诚</p>
  <div class="site-description" itemprop="description">命运对勇士低语，你无法抵御风暴；勇士低声回应，我就是风暴</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/wang-cheng/archives/">
        
          <span class="site-state-item-count">32</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/wang-cheng/tags/">
          
        <span class="site-state-item-count">12</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">王诚</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
  </div>

        
<div class="busuanzi-count">
  <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <span class="post-meta-item" id="busuanzi_container_site_uv" style="display: none;">
      <span class="post-meta-item-icon">
        <i class="fa fa-user"></i>
      </span>
      <span class="site-uv" title="总访客量">
        <span id="busuanzi_value_site_uv"></span>
      </span>
    </span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item" id="busuanzi_container_site_pv" style="display: none;">
      <span class="post-meta-item-icon">
        <i class="fa fa-eye"></i>
      </span>
      <span class="site-pv" title="总访问量">
        <span id="busuanzi_value_site_pv"></span>
      </span>
    </span>
</div>








      </div>
    </footer>
  </div>

  
  <script src="/wang-cheng/lib/anime.min.js"></script>
  <script src="/wang-cheng/lib/velocity/velocity.min.js"></script>
  <script src="/wang-cheng/lib/velocity/velocity.ui.min.js"></script>

<script src="/wang-cheng/js/utils.js"></script>

<script src="/wang-cheng/js/motion.js"></script>


<script src="/wang-cheng/js/schemes/pisces.js"></script>


<script src="/wang-cheng/js/next-boot.js"></script>




  















  

  

  

</body>
</html>
